package com.xsg.printer.core;

import com.xsg.printer.core.enums.*;
import com.xsg.printer.core.model.*;
import com.xsg.printer.core.toolkit.*;

import java.awt.*;
import java.util.HashMap;
import java.util.List;

public class VoucherImagePaint extends VoucherPaint<Graphics2D>{

    public VoucherImagePaint(Graphics2D container) {
        super(container);
    }

    protected void initElementSizeCalMap() {
        elementCalSizeMap = new HashMap<>();
        //文字大小计算函数
        elementCalSizeMap.put(ElementTypeEnum.TEXT.getType(), new ElementSizeCalculator<XsgElementText>() {
            @Override
            public int width(XsgElementText element) {
                return element.getWidth();
            }

            @Override
            public int height(XsgElementText element) {
                return element.getHeight();
            }
        });

        //二维码大小计算函数
        elementCalSizeMap.put(ElementTypeEnum.QR.getType(), new ElementSizeCalculator<XsgElementQrCode>() {
            @Override
            public int width(XsgElementQrCode element) {
                return element.getWidth();
            }

            @Override
            public int height(XsgElementQrCode element) {
                return element.getHeight();
            }
        });

        //条形码大小计算函数
        elementCalSizeMap.put(ElementTypeEnum.BAR.getType(), new ElementSizeCalculator<XsgElementBarCode>() {
            @Override
            public int width(XsgElementBarCode element) {
                return element.getWidth();
            }

            @Override
            public int height(XsgElementBarCode element) {
                return element.getHeight();
            }
        });

        //图片大小计算函数
        elementCalSizeMap.put(ElementTypeEnum.IMAGE.getType(), new ElementSizeCalculator<XsgElementImage>() {
            @Override
            public int width(XsgElementImage element) {
                return element.getWidth();
            }

            @Override
            public int height(XsgElementImage element) {
                return element.getHeight();
            }
        });

        //圆大小计算函数
        elementCalSizeMap.put(ElementTypeEnum.CIRCLE.getType(), new ElementSizeCalculator<XsgElementCircle>() {
            @Override
            public int width(XsgElementCircle element) {
                return element.getWidth();
            }

            @Override
            public int height(XsgElementCircle element) {
                return element.getHeight();
            }
        });
    }

    @Override
    public void drawLine(XsgCoordinate start, XsgCoordinate end, int borderType, int color) {
        container.setColor(ColorEnum.getColorByType(color));
        ImageLinePaint.DrawLine<Graphics2D> drawLine = BorderStyleEnum.getEnumByType(borderType).getImageValue();
        if (drawLine != null) {
            drawLine.draw(container, start, end);
        }
    }

    @Override
    public void drawQrCode(String value, XsgCoordinate start, int width, int height) {
        try {
            String path = QRCodeUtil.drawQRCode(value, width , height);
            if (path != null) {
                drawImage(path, false, start, width, height);
                FileWriterUtils.clearFile(path);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void drawBarCode(String value, XsgCoordinate start, int width, int height) {
        try {
            String path = BarcodeUtil.drawBarcode(value, width, height);
            if (path != null) {
                drawImage(path, false, start, width, height);
                FileWriterUtils.clearFile(path);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void drawImage(String sourcePath, boolean isRemote, XsgCoordinate start, int width, int height) {
        Image image;
        try {
            if (isRemote) {
                String path = ImageUtil.download(sourcePath);
                if (path != null) {
                    image = ImageUtil.readImage(path, width, height, true);
                    container.drawImage(image, start.getX(), start.getY(), null);
                    FileWriterUtils.clearFile(path);
                }
            } else {
                image = ImageUtil.readImage(sourcePath, width, height, true);
                container.drawImage(image, start.getX(), start.getY(), null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int drawString(String value, XsgCoordinate start, int width, int height, XsgFont xsgfont) {
        if (value == null || value.isEmpty() || width <= 0 || height <= 0) {
            return 0;
        }
        container.setColor(ColorEnum.getColorByType(xsgfont.getColor()));
        container.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Integer fontStyle = FontStyleEnum.getEnumByType(xsgfont.getFontStyle()).getImageValue();
        Integer fontSize = FontSizeEnum.getEnumByType(xsgfont.getFontSize()).getImageValue();
        Font font = new Font(FontFamilyEnum.getNameByType(xsgfont.getFontFamily()), fontStyle == null ? Font.PLAIN : fontStyle, fontSize);
        container.setFont(font);
        CalStartCoordinate calStartCoordinate = alignStartCoordinateMap.get(xsgfont.getAlign());
        if (calStartCoordinate == null) {
            calStartCoordinate = alignStartCoordinateMap.get(AlignEnum.TOP_LEFT.getCode());
        }
        FontMetrics fontMetrics = container.getFontMetrics();
        List<XsgFontLine> fontLines = FontUtil.getFontLines(width, height, value, fontMetrics);
        int totalHeight = fontLines.stream().mapToInt(XsgFontLine::getHeight).sum();
        XsgCoordinate yCoordinate = calStartCoordinate.cal(start, width, height, 0, totalHeight);
        //防止换行时候向上冲出限制范围
        if (yCoordinate.getY() < start.getY()) {
            yCoordinate.setY(start.getY());
        }
        int ascent = fontMetrics.getAscent();
        int decent = fontMetrics.getDescent();
        int standY = yCoordinate.getY() + ascent - (ascent + decent - fontSize) / 2;
        for (XsgFontLine fontLine : fontLines) {
            XsgCoordinate xCoordinate = calStartCoordinate.cal(start, width, height, fontLine.getWidth(), 0);
            container.drawString(fontLine.getValue(), xCoordinate.getX() , standY);
            standY = standY + fontMetrics.getHeight();
            if (xsgfont.isNeedFeedLine()) {
                continue;
            } else {
                break;
            }
        }
        return 0;
    }

    @Override
    public void drawCircle(String value, XsgCoordinate start, int width, int height, XsgFont font) {
        container.setColor(Color.BLACK);
        container.drawOval(start.getX(), start.getY(), width, height);
        drawString(value, start, width, height, font);
    }
}
